package com.yuns.netty.chat;

import com.alibaba.fastjson.JSON;

import com.yuns.netty.chat.param.Message;
import com.yuns.netty.chat.param.TbChatRecord;
import com.yuns.netty.param.UserChannelMap;
import com.yuns.util.SpringBeanUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 处理消息的handler
 * TextWebSocketFrame: 在netty中，是用于为websocket专门处理文本的对象，frame是消息的载体
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    // 用来保存所有的客户端连接
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:MM");

    // 当Channel中有新的事件消息会自动调用
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        // 当接收到数据后会自动调用
        // 获取客户端发送过来的文本消息
        String text = msg.text();
        System.out.println("接收到消息数据为：" + text);
        Message message = JSON.parseObject(text, Message.class);
        RedisTemplate redisTemplate = (RedisTemplate) SpringBeanUtil.getBean("redisTemplate");
        switch (message.getType()) {
            // 处理客户端连接的消息
            case 0:
                // 建立用户与通道的关联
                Integer userId = message.getChatRecord().getUserId();
                if (userId == null) {
                    TbChatRecord tbChatRecord = new TbChatRecord();
                    tbChatRecord.setMessage("当前用户不存在");
                    message.setChatRecord(tbChatRecord);
                    ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));
                    ctx.channel().close();
                } else {
                    UserChannelMap.put(userId, message.getDeviceType(), ctx.channel());
                    System.out.println("建立用户:" + userId + "与通道" + ctx.channel().id() + "的关联");
                    UserChannelMap.print();
                    ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));
                }
                break;
            // 处理客户端发送好友消息
            case 1:
                System.out.println("接收到用户消息");
                break;
            // 处理客户端的签收消息
            case 2:
                break;
            case 3:
                //接收到心跳消息
                System.out.println("接收到心跳消息:" + JSON.toJSONString(message));
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));
                break;
            case 4:
                break;
            case 7:
                break;
        }
    }

    // 当有新的客户端连接服务器之后，会自动调用这个方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 将新的通道加入到clients
        clients.add(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Message message = new Message();
        message.setType(9);
        TbChatRecord tbChatRecord = new TbChatRecord();
        tbChatRecord.setType(9);
        tbChatRecord.setCreateTime(new Date());
        tbChatRecord.setHasRead(0);
        tbChatRecord.setMessage(cause.getMessage() + "通讯异常");
        message.setChatRecord(tbChatRecord);
        ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
        System.out.println(cause.getMessage() + "通讯异常");
        ctx.channel().close();
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("关闭通道");
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
        UserChannelMap.print();
    }


}
